﻿using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.ComponentModel;
using System.Xml;
using System.Windows.Threading;
using Eniux.Windows.Controls.WindowCore;
using System.Windows.Input;
using System.Collections.ObjectModel;
using ThemeManagementModule.Models;
using System.Windows.Media.Imaging;
using System.IO;

namespace ThemeManagementModule
{
    /// <summary>
    /// ThemeMngView.xaml 的交互逻辑
    /// </summary>
    public partial class ThemeMngView :WindowBase, INotifyPropertyChanged
    {
        DispatcherTimer timer;
        public ThemeMngView()
        {
            InitializeComponent();
            Loaded += new RoutedEventHandler(ThemeMngView_Loaded);
            Closing += new CancelEventHandler(ThemeMngView_Closing);
            this.DataContext = this;

        }

        void ThemeMngView_Closing(object sender, CancelEventArgs e)
        {
            SaveConfig();
        }

        void ThemeMngView_Loaded(object sender, RoutedEventArgs e)
        {
            LoadConfig();
            SetBasicColors();
        }

        XmlDocument ConfigXml;
        #region 私有变量
        private int _selectedImageIndex;
        private SolidColorBrush _mainBackground=new SolidColorBrush();
        private int _opacity=255;
        string[] str = new string[] { "FF", "CC", "99", "66", "33", "00" };
        private ObservableCollection<ThemeModel> _backImageCollection = new ObservableCollection<ThemeModel>();
        #endregion

        #region 属性
        public ObservableCollection<ThemeModel> BackImageCollection
        {
            get { return _backImageCollection; }
            set { _backImageCollection = value; }
        }
        public int SelectedImageIndex
        {
            get { return _selectedImageIndex; }
            set
            {
                if (_selectedImageIndex != value)
                {
                    _selectedImageIndex = value;
                    NotifyPropertyChanged("SelectedImageIndex");
                }
            }
        }
        public SolidColorBrush MainBackground
        {
            get { return _mainBackground; }
            set 
            { 
                _mainBackground= value;
                NotifyPropertyChanged("MainBackground");
            }
        }
        public int BackOpacity
        {
            get { return _opacity; }
            set
            { 
                _opacity = value;
                NotifyPropertyChanged("BackOpacity");
            }
        }
        #endregion
        #region INotifyPropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string propertyName)
        {
            if (this.PropertyChanged != null)
            {
                this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
        }
        #endregion

        void LoadConfig()
        {
            ConfigXml = new XmlDocument();

            try
            {
                ConfigXml.Load(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"theme\themeconfig.xml"));
                XmlElement OpacityList = (XmlElement)ConfigXml.SelectSingleNode("/ThemeInfo/Opacity");
                LoadOpacityConfig(OpacityList);
                XmlNodeList list = ConfigXml.SelectNodes("/ThemeInfo/BackImageList/BackImage");
                LoadBackImageConfig(list);
                XmlNode list2 = ConfigXml.SelectSingleNode("/ThemeInfo/Background");
                LoadBackgroundConfig(list2);
            }
            catch (Exception)
            {
            }
        }

          void LoadOpacityConfig(XmlElement node)
        {
            if (node.Attributes["Value"] != null)
            {
                BackOpacity = int.Parse(node.Attributes["Value"].Value);
            }
            else
                BackOpacity = 255;
        }

        void LoadBackImageConfig(XmlNodeList list)
        {
            int i = 0,j=0;
            foreach (XmlNode node in list)
            {
               
                ThemeModel tm = new ThemeModel();
                if (node.Attributes["Value"] != null)
                {
                    tm.SourceValue = node.Attributes["Value"].Value;
                    tm.Value = "pack://siteOfOrigin:,,,/theme/images/" + node.Attributes["Value"].Value;
                }
                if (node.Attributes["IsSelected"] != null)
                {
                    j = i;
                }
                BackImageCollection.Add(tm);
                i++;
            }
            ThemeModel addtm= new ThemeModel();
            addtm.SourceValue = "add.png";
            addtm.Value = "/ThemeManagementModule;component/add.png";
            addtm.DC = (DoubleCollection)new DoubleCollectionConverter().ConvertFromString("5 5");//new DoubleCollection(new
            BackImageCollection.Add(addtm);
            SelectedImageIndex = j;


        }
        void LoadBackgroundConfig(XmlNode node)
        {
            foreach (XmlNode _node in node.ChildNodes)
            {
                if (_node.Attributes["Value"].Value != null)
                {
                    MainBackground.Color = (Color)ColorConverter.ConvertFromString(_node.Attributes["Value"].Value);
                    if (_node.Attributes["IsSelected"].Value != null && bool.Parse(_node.Attributes["IsSelected"].Value))
                    {
                        SetBackground(MainBackground.Color, BackOpacity);
                        SelectedImageIndex = -1;
                        SetBackImage(null, BackOpacity);
                    }
                } 
            }
        }
        private void ChangeOpacity_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
        {
            SetBackground((Application.Current.FindResource("Theme_Window_Background") as SolidColorBrush).Color, BackOpacity);
            SetBackImage((Application.Current.FindResource("Theme_Window_BackImage") as ImageBrush).ImageSource,BackOpacity);
        }

        #region 填充选色板及相关处理事件
        void SetBasicColors()
        {
            #region 填充右侧基本颜色面板
            for (int i = 0; i < 12; i++)
            {
                for (int j = 0; j < 18; j++)
                {
                    if (i < 6)
                    {
                        if (j < 6)
                        {
                            addChildren(this.right_root, "CC", str[i], str[j]);
                        }
                        if (j >= 6 && j < 12)
                        {
                            addChildren(this.right_root, "66", str[i], str[11 - j]);
                        }
                        if (j >= 12 && j < 18)
                        {
                            addChildren(this.right_root, "00", str[i], str[j - 12]);
                        }
                    }
                    else
                    {
                        if (j < 6)
                        {
                            addChildren(this.right_root, "FF", str[11 - i], str[j]);
                        }
                        if (j >= 6 && j < 12)
                        {
                            addChildren(this.right_root, "99", str[11 - i], str[11 - j]);
                        }
                        if (j >= 12 && j < 18)
                        {
                            addChildren(this.right_root, "33", str[11 - i], str[j - 12]);
                        }
                    }
                }
            }
            #endregion

            #region 填充左侧基本颜色面板
            for (int i = 0; i < 3; i++)
            {
                for (int j = 0; j < 12; j++)
                {
                    if (i == 0 || i == 2)
                    {
                        addChildren(this.left_root, "00", "00", "00");
                    }
                    else
                    {
                        if (j < 6)
                        {
                            addChildren(this.left_root, str[5 - j], str[5 - j], str[5 - j]);
                        }
                        else
                        {
                            switch (j)
                            {
                                case 6: { addChildren(this.left_root, "FF", "00", "00"); break; }
                                case 7: { addChildren(this.left_root, "00", "FF", "00"); break; }
                                case 8: { addChildren(this.left_root, "00", "00", "FF"); break; }
                                case 9: { addChildren(this.left_root, "FF", "FF", "00"); break; }
                                case 10: { addChildren(this.left_root, "00", "FF", "FF"); break; }
                                case 11: { addChildren(this.left_root, "FF", "00", "FF"); break; }
                            }
                        }
                    }
                }
            }
            #endregion
        }
        void addChildren(WrapPanel wp, string colorR, string colorG, string colorB)
        {
            Border bd = new Border();
            bd.Background = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#" + colorR + colorG + colorB));
            bd.BorderThickness = new Thickness(1, 1, 0, 0);
            bd.BorderBrush = Brushes.Black;
            bd.ToolTip = "#" + colorR + colorG + colorB;
            bd.SnapsToDevicePixels = true;
            bd.MouseEnter += new MouseEventHandler(bd_MouseEnter);
            bd.MouseLeave += new MouseEventHandler(bd_MouseLeave);
            bd.MouseDown += new MouseButtonEventHandler(bd_MouseDown);
            wp.Children.Add(bd);
        }

        void bd_MouseDown(object sender, MouseButtonEventArgs e)
        {
            Color selectColor = (Color)ColorConverter.ConvertFromString("#" + (sender as Border).Background.ToString().Substring(3, 6));
            MainBackground = new SolidColorBrush() { Color = Color.FromArgb(selectColor.A, selectColor.R, selectColor.G, selectColor.B) };


            SetBackground(MainBackground.Color, BackOpacity);
            SelectedImageIndex = -1;
            SetBackImage(null,BackOpacity);
        }

        void bd_MouseLeave(object sender, MouseEventArgs e)
        {
            (sender as Border).Child = null;
        }

        void bd_MouseEnter(object sender, MouseEventArgs e)
        {
            Border bd2 = new Border();
            bd2.Background = Brushes.Transparent;
            bd2.BorderThickness = new Thickness(1);
            if ((sender as Border).Background.ToString() == Brushes.Black.ToString())
            {
                bd2.BorderBrush = Brushes.White;
            }
            else if ((sender as Border).Background.ToString() == "#FF333366" ||
                (sender as Border).Background.ToString() == "#FF333333")
            {
                bd2.BorderBrush = Brushes.White;
            }
            else if ((sender as Border).Background.ToString() == "#FF666666"
                || (sender as Border).Background.ToString() == "#FF999999"
                || (sender as Border).Background.ToString() == "#FFCCCCCC"
                || (sender as Border).Background.ToString() == "#FFFFFFFF")
            {
                bd2.BorderBrush = Brushes.OrangeRed;
            }
            else
            {
                byte _r = ((SolidColorBrush)((sender as Border).Background)).Color.R;
                byte _g = ((SolidColorBrush)((sender as Border).Background)).Color.G;
                byte _b = ((SolidColorBrush)((sender as Border).Background)).Color.B;
                byte r = 30;
                byte g = 30;
                byte b = 30;
                if (_r == 0)
                {
                    r = 255;
                }
                if (_g == 0)
                {
                    g = 255;
                }
                if (_b == 0)
                {
                    b = 255;
                }
                bd2.BorderBrush = new SolidColorBrush((Color)Color.FromRgb(r, g, b));
            }


            (sender as Border).Child = bd2;
        } 
        #endregion

        private void SetBackImage(ImageSource source, int opacity)
        {
            ImageBrush imgbrush = new ImageBrush();
            imgbrush.Stretch = Stretch.Fill;
            imgbrush.TileMode =TileMode.Tile;
            imgbrush.Viewbox = new Rect(0, 0, 1, 1); ;
            imgbrush.ViewboxUnits = BrushMappingMode.RelativeToBoundingBox;
            imgbrush.ImageSource = source;
            imgbrush.Opacity = opacity / 255.0;
            Application.Current.Resources["Theme_Window_BackImage"] = imgbrush;
        }

        private void SetBackground(Color c, int opacity)
        {
            SolidColorBrush brush = new SolidColorBrush();
            brush.Color = c;
            brush.Opacity = opacity / 255.0;
            Application.Current.Resources["Theme_Window_Background"] = brush;
            Application.Current.Resources["Theme_Window_Background_NoTransparent"] = new SolidColorBrush() { Color = c };
        }

        private void BackImageRoot_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (SelectedImageIndex != BackImageCollection.Count - 1&&SelectedImageIndex>=0)
            {
                ImageSource imgsource=(ImageSource)new ImageSourceConverter().ConvertFromString(BackImageCollection[SelectedImageIndex].Value);
                SetBackImage(imgsource, BackOpacity);
                if(MainBackground!=null)
                    SetBackground(MainBackground.Color,0);
            }
            if (SelectedImageIndex == BackImageCollection.Count - 1)
            {
                SelectedImageIndex = tmpindex;
                System.Windows.Forms.OpenFileDialog dialog = new System.Windows.Forms.OpenFileDialog();
                dialog.Filter = "文本文件(*.png)|*.png";
                dialog.Multiselect = false;

                if (dialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
                {
                    try
                    {
                        FileInfo fi = new FileInfo("ssS");
                        File.Copy(dialog.FileName, System.IO.Path.Combine(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"theme\images\", System.IO.Path.GetFileName(dialog.FileName))));
                    }
                    catch (Exception ex)
                    {
                        WindowBase.ShowMessageBox("提示", ex.Message, MessageBoxImage.Error, MessageBoxButton.OK);
                        return;
                    }
                    ThemeModel tm = new ThemeModel();
                    tm.SourceValue = dialog.SafeFileName;
                    tm.Value = System.IO.Path.Combine(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory + @"theme\images\" + dialog.SafeFileName));

                    BackImageCollection.Insert(BackImageCollection.Count - 1, tm);
                    SelectedImageIndex = BackImageCollection.Count - 2;
                }
            }
        }
        
        //XmlNode imagelist;
        private void SaveConfig()
        {
            XmlNode imagelist = ConfigXml.SelectSingleNode("/ThemeInfo/BackImageList");
            imagelist.RemoveAll();
            foreach (ThemeModel tm in BackImageCollection)
            {
                if (tm!=BackImageCollection[BackImageCollection.Count-1])
                {
                    XmlElement node = ConfigXml.CreateElement("BackImage");
                    if (tm.SourceValue != null)
                    {
                        node.SetAttribute("Value", tm.SourceValue);
                    }
                    if (SelectedImageIndex >= 0&&tm == BackImageCollection[SelectedImageIndex])
                    {
                        node.SetAttribute("IsSelected", true.ToString());
                    }
                    imagelist.AppendChild(node); 
                }
            }
            ConfigXml.SelectSingleNode("/ThemeInfo/Opacity").Attributes["Value"].Value=BackOpacity.ToString();

            XmlElement backgroundnode = (XmlElement)ConfigXml.SelectSingleNode("/ThemeInfo/Background");
            backgroundnode.SetAttribute("Value", MainBackground.Color.ToString());
            if ((Application.Current.Resources["Theme_Window_BackImage"] as ImageBrush).ImageSource == null)
                backgroundnode.SetAttribute("IsSelected", true.ToString());
            System.IO.File.SetAttributes(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"theme\themeconfig.xml"), System.IO.FileAttributes.Normal);
            ConfigXml.Save(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"theme\themeconfig.xml"));
        }

        int tmpindex = 0;
        private void BackImageRoot_PreviewMouseDown(object sender, MouseButtonEventArgs e)
        {
            tmpindex = SelectedImageIndex;
        }

    }
   public static class InitTheme
    {
     private static  XmlDocument ConfigXml;
     private static ImageSource Imgsource;
     private static SolidColorBrush Background;
     private static int Opacity;
     public static  void LoadConfig()
       {
           ConfigXml = new XmlDocument();

           try
           {
               ConfigXml.Load(System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, @"theme\themeconfig.xml"));
               XmlElement OpacityList =(XmlElement)ConfigXml.SelectSingleNode("/ThemeInfo/Opacity");
               LoadOpacityConfig(OpacityList);
               XmlNodeList list = ConfigXml.SelectNodes("/ThemeInfo/BackImageList/BackImage");
               
               LoadBackImageConfig(list);
               XmlNode list2 = ConfigXml.SelectSingleNode("/ThemeInfo/Background");
               LoadBackgroundConfig(list2);
               SetBackImage(Imgsource, Opacity);
               SetBackground(Background.Color, Opacity);
               
           }
           catch (Exception)
           {
           }
       }
     private static void LoadOpacityConfig(XmlElement node)
       {
           if (node.Attributes["Value"] != null)
               {
                   Opacity = int.Parse(node.Attributes["Value"].Value);
               }
               else
                   Opacity = 255;
       }
     private static void LoadBackImageConfig(XmlNodeList list)
       {
           foreach (XmlNode node in list)
           {
               ThemeModel tm = new ThemeModel();
               if (node.Attributes["Value"] != null)
               {
                   tm.SourceValue = node.Attributes["Value"].Value;
                   tm.Value = "pack://siteOfOrigin:,,,/theme/images/" + node.Attributes["Value"].Value;
               }
               if (node.Attributes["IsSelected"] != null)
               {
                   Imgsource =(ImageSource)new ImageSourceConverter().ConvertFromString(tm.Value);
               }
           }
       }
     private static void LoadBackgroundConfig(XmlNode node)
       {
           foreach (XmlNode _node in node.ChildNodes)
           {
               if (_node.Attributes["Value"].Value != null)
               {
                   if (_node.Attributes["IsSelected"].Value != null && bool.Parse(_node.Attributes["IsSelected"].Value))
                   {
                       Background = new SolidColorBrush() { Color = (Color)ColorConverter.ConvertFromString(_node.Attributes["Value"].Value) };
                   }
               }
           }
       }
       private static void SetBackImage(ImageSource source, int opacity)
       {
           ImageBrush imgbrush = new ImageBrush();
           imgbrush.Stretch = Stretch.Fill;
           imgbrush.TileMode = TileMode.Tile;
           imgbrush.Viewbox = new Rect(0, 0, 1, 1); ;
           imgbrush.ViewboxUnits = BrushMappingMode.RelativeToBoundingBox;
           imgbrush.ImageSource = source;
           imgbrush.Opacity = opacity / 255.0;
           Application.Current.Resources["Theme_Window_BackImage"] = imgbrush;
       }

       private static void SetBackground(Color c, int opacity)
       {
           SolidColorBrush brush = new SolidColorBrush();
           brush.Color = c;
           brush.Opacity = opacity / 255.0;
           Application.Current.Resources["Theme_Window_Background"] = brush;
           Application.Current.Resources["Theme_Window_Background_NoTransparent"] = new SolidColorBrush() { Color = c };
       }
    }
}
